//
// Created by martin on 4/19/22.
//

#ifndef MUDUO_PROTOBUFCODECLITE_H
#define MUDUO_PROTOBUFCODECLITE_H

#include "muduo/base/noncopyable.h"
#include "muduo/base/StringPiece.h"
#include "muduo/base/Timestamp.h"
#include "muduo/net/Callbacks.h"

#include <memory>
#include <type_traits>

namespace google
{
namespace protobuf
{
class Message;
}
}

namespace muduo
{
namespace net
{

typedef std::shared_ptr<google::protobuf::Message> MessagePtr;

// wire format
//
// Field        Length  Content
//
// size         4-byte  M+N+4
// tag          M-byte  could be "RPC0", etc.
// payload      N-byte
// checksum     4-byte  adler32 of tag+payload
//
// This is an internal class, you should use ProtobufCodecT instead.
class ProtobufCodecLite : noncopyable
{
public:
    const static int kHeaderLen = sizeof(int32_t);
    const static int kCheckSumLen = sizeof(int32_t);
    const static int kMaxMessageLen = 64*1024*1024; // same as codec_stream.h kDefaultTotalBytesLimit

    enum ErrorCode
    {
        kNoError = 0,
        kInvalidLength,
        kCheckSumError,
        kInvalidNameLen,
        kUnknownMessageType,
        kParseError,
    };

    // return false to stop parsing protobuf message
    typedef std::function<bool (const TcpConnectionPtr&,
            StringPiece,
            Timestamp)> RawMessageCallback;

    typedef std::function<void (const TcpConnectionPtr&,
            const MessagePtr&,
            Timestamp)> ProtobufMessageCallback;

    typedef std::function<void (const TcpConnectionPtr&,
            Buffer*,
            Timestamp,
            ErrorCode)> ErrorCallback;

    ProtobufCodecLite(const ::google::protobuf::Message* prototype,
                      StringPiece tagArg,
                      const ProtobufMessageCallback& messageCb,
                      const RawMessageCallback& rawCb = RawMessageCallback(),
                      const ErrorCallback& errorCb = defaultErrorCallback)
    : prototype_(prototype)
    {}

private:
    const ::google::protobuf::Message* prototype_;
    const string tag_;
    ProtobufMessageCallback messageCallback_;
    RawMessageCallback rawCb_;
    ErrorCallback errorCallback_;
    const int kMinMessageLen;
};

}
}




#endif //MUDUO_PROTOBUFCODECLITE_H
